#ifndef _RINGQUEUE_HPP_
#define _RINGQUEUE_HPP_

#include "Mutex.hpp"
#include "Sem.hpp"
#include <vector>

const int gcap = 5;

namespace Ring
{
    template <class T>
    class Ringqueue
    {
    public:
        Ringqueue(int cap = gcap)
            : _ringqueue(cap)
            , _cap(cap)
            ,_blank_sem(cap) // 空位置个数
            ,_data_sem(0) // 有效位置个数
            ,_p_step(0)
            , _c_step(0)
        {
        }
        ~Ringqueue()
        {
            ;
        }
        void Enqueue(const T& in)
        {
            // 申请信号量。
            // --
            _blank_sem.P();

            {
                // 申请锁。
                //_productor_lock.Lock();

                Lock_Manager lock_manager(_productor_lock);

                _ringqueue[_p_step++] = in;

                _p_step %= _cap;

                //_productor_lock.Unlock();
            }

            // ++
            //_blank_sem.V();
            _data_sem.V();
        }
        T Pop()
        {
            T data;

            // --
            _data_sem.P();

            {
                //_consumer_lock.Lock();

                Lock_Manager lockmanager(_consumer_lock);

                data = _ringqueue[_c_step++];

                _c_step %= _cap;

                //_consumer_lock.Unlock();
            }

            // ++
            // _data_sem.V();
            _blank_sem.V();

            return data;
        }
    private:
        std::vector<T> _ringqueue;

        int _cap;

        Sem _blank_sem;
        Sem _data_sem;

        Mutex _productor_lock;
        Mutex _consumer_lock;

        int _p_step;
        int _c_step;
    };
}

#endif